"""
Case Type   : CM_Tools
Case Name   : cm_ctl query查看数据库状态基本参数验证
Create At   : 2025/5/20
Owner       : ningyali
Description :
    1.显示详细数据库状态
    2.按主备关系成对显示数据库状态(使用-C必须指定-v)
    3.显示备机redo状态(使用-r必须指定-v)
    4.显示导致各个节点主备实例数量不均衡的实例(使用-s必须指定-v和-C)
    5.显示数据库启动时的状态检查结果(使用-S必须指定-v和-C)
    6.显示各个节点Fenced UDF状态(使用-F必须指定-v和-C)
    7.显示物理节点ip(使用-i必须指定-v和-C)
    8.显示实例数据目录(使用-d必须指定-v和-C)
    9.显示数据库所有实例AZ名称(-z参数需要和-v以及-C参数一起使用，
    10.显示数据库所有异常实例(使用-x必须指定-v和-C)
    11.显示数据库所有DN端口(使用-p必须指定-v和-C)
    12.只查询指定AZ的cms
    13.不符合参数搭配情况
Expect      :
    1.执行成功
    2.执行成功
    3.执行成功
    4.执行成功
    5.执行成功
    6.执行成功
    7.执行成功
    8.执行成功
    9.执行成功
    10.执行成功
    11.执行成功
    12.执行成功
    13.执行成功
History     :
"""

import os
import time
import unittest

from testcase.utils.ComInstall import CmInstall
from testcase.utils.ComInstall import CmUnInstall
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class CMServer(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.root_nodes = (Node('PrimaryRoot'), Node('Standby1Root'),
                           Node('Standby2Root'))
        self.user_nodes = (Node('PrimaryDbUser'), Node('Standby1DbUser'),
                           Node('Standby2DbUser'))
        self.common = Common()

        text = '----prestep1:安装cm;expect:执行成功----'
        self.log.info(text)
        self.install_pkg_path = os.path.dirname(macro.DB_SCRIPT_PATH)
        self.cm = CmInstall(self.install_pkg_path, self.pri_sh.node.ssh_user)
        res = self.cm.update_xml_for_cm(*self.root_nodes)
        self.assertGreater(res.count('cmDir'), 1, f'执行失败: {text}')

        res = self.cm.cm_install(self.user_nodes[0])
        self.assertIn('Install CM tool success', res, f'执行失败: {text}')

    def test_trans(self):
        text = '----step1:显示详细数据库状态;expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};cm_ctl query -v"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertNotIn('error', q_res.lower(), f'执行失败: {text}')

        text = '----step2:按主备关系成对显示数据库状态(使用-C必须指定-v);expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};cm_ctl query -v -C"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertNotIn('error', q_res.lower(), f'执行失败: {text}')

        text = '----step3:显示备机redo状态(使用-r必须指定-v);expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};cm_ctl query -v -r"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertNotIn('error', q_res.lower(), f'执行失败: {text}')

        text = '----step4:显示导致各个节点主备实例数量不均衡的实例(使用-s必须指定-v和-C);expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};cm_ctl query -v -C -s"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertNotIn('error', q_res.lower(), f'执行失败: {text}')

        text = '----step5:显示数据库启动时的状态检查结果(使用-S必须指定-v和-C);expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};cm_ctl query -v -C -S"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertNotIn('error', q_res.lower(), f'执行失败: {text}')

        text = '----step6:显示各个节点Fenced UDF状态(使用-F必须指定-v和-C);expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};cm_ctl query -v -C -F"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertNotIn('error', q_res.lower(), f'执行失败: {text}')

        text = '----step7:显示物理节点ip(使用-i必须指定-v和-C);expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};cm_ctl query -v -C -i"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertNotIn('error', q_res.lower(), f'执行失败: {text}')

        text = '----step8:显示实例数据目录(使用-d必须指定-v和-C);expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};cm_ctl query -v -C -d"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertNotIn('error', q_res.lower(), f'执行失败: {text}')

        text = '----step9:显示数据库所有实例AZ名称(-z参数需要和-v以及-C参数一起使用，' \
               '并且-z后面需要跟参数ALL);expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};cm_ctl query -v -C -z ALL"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertNotIn('error', q_res.lower(), f'执行失败: {text}')

        text = '----step10:显示数据库所有异常实例(使用-x必须指定-v和-C);expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};cm_ctl query -v -C -x"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertNotIn('error', q_res.lower(), f'执行失败: {text}')

        text = '----step11:显示数据库所有DN端口(使用-p必须指定-v和-C);expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};cm_ctl query -v -C -p"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertNotIn('error', q_res.lower(), f'执行失败: {text}')

        text = '----step12:只查询指定AZ的cms;expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};cm_ctl query -v --minorityAz=AZ1"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertNotIn('error', q_res.lower(), f'执行失败: {text}')

        text = '----step13:不符合参数搭配情况;expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};cm_ctl query -C"
        q_cmd1 = f"source {macro.DB_ENV_PATH};cm_ctl query -r"
        q_cmd2 = f"source {macro.DB_ENV_PATH};cm_ctl query -S"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        q_res1 = self.common.get_sh_result(self.user_nodes[0], q_cmd1)
        q_res2 = self.common.get_sh_result(self.user_nodes[0], q_cmd2)
        expect = 'cm_ctl: Try "cm_ctl --help" for more information'
        self.assertIn(expect, q_res, f'执行失败: {text}')
        self.assertIn(expect, q_res1, f'执行失败: {text}')
        self.assertIn(expect, q_res2, f'执行失败: {text}')

    def tearDown(self):
        text = '----poststep1:还原集群;expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};cm_ctl query -v -C -i -d"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        if 'Standby Normal' in q_res.splitlines()[-1].split('|')[0]:
            switch_cmd = f"source {macro.DB_ENV_PATH}; cm_ctl switchover -a;"
            self.common.get_sh_result(self.user_nodes[0], switch_cmd)
            time.sleep(5)
            q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)

        text = '----poststep2:卸载cm;expect:执行成功----'
        self.log.info(text)
        self.un_cm = CmUnInstall(self.install_pkg_path,
                                 self.pri_sh.node.ssh_user)
        res = self.un_cm.cm_uninstall(
            self.user_nodes[0], '--deleteData --deleteBinary')

        self.assertTrue(
            'Primary Normal' in q_res and q_res.count('Standby Normal') == 2,
            f'执行失败: {text}')
        self.assertIn('Uninstall CM tool success', res, f'执行失败: {text}')
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
